package com.example.springframework.beans.factory.support;

import com.example.springframework.beans.BeansException;
import com.example.springframework.beans.factory.BeanFactory;
import com.example.springframework.beans.factory.config.BeanDefinition;

/**
 * @fileName: {@link AbstractBeanFactory}
 * @author: yyfl
 * @date: 2023/2/23 14:45
 * @description:
 * @history:
 *
 * 该抽象类的主要作用是实现了顶级的DefaultSingletonBeanRegistry的方法
 *   1、实现了获取Bean容器中的实例化对象
 *   2、当没有获取到时会自动实例化，并保存到单例对象当中去
 *
 *  AbstractBeanFactory 继承了 DefaultSingletonBeanRegistry类 实现了 BeanFactory
 *  DefaultSingletonBeanRegistry 实现了 SingletonBeanRegistry
 *
 *  AbstractBeanFactory 首先继承了 DefaultSingletonBeanRegistry 那么就具备了单例注册类的方法
 */
public abstract class AbstractBeanFactory extends  DefaultSingletonBeanRegistry implements BeanFactory {

    /**
     * 1、获取Bean实例对象
     * 2、当 DefaultSingletonBeanRegistry 中并没有获取到Bean实例的时候，那么就需要做相应的实例化bean的操作
     * 3、而getBean并没有实现这些方法
     * 4、而是只定义了调用过程和提供了抽象方法
     * 5、那么这两个方法由后续继承 AbstractBeanFactory 这个抽象类的类进行实现
     * 6、后续有继承的类有 AbstractAutowireCapableBeanFactory 、 DefaultListableBeanFactory
     *
     * @param name Bean名称
     * @return Bean实例
     * @throws BeansException 。
     */
    @Override
    public Object getBean(String name) throws BeansException{
        Object singleton = getSingleton(name);

        if (singleton != null){
            return singleton;
        }

        // 获取Bean的定义
        BeanDefinition beanDefinition = getBeanDefinition(name);

        // 做实例化操作并保存
        return createBeanDefinition(name, beanDefinition);
    }

    /**
     * 获取Bean定义对象
     *
     * @param beanName Bean名称
     * @return 定义对象
     * @throws BeansException 。
     */
    public abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;

    /**
     * 实例化Bean的定义对象并保存
     *
     * @param beanName Bean名称
     * @param beanDefinition 定义对象
     * @return 实例化后的对象
     * @throws BeansException 。
     */
    public abstract Object createBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeansException;
}
